﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FCTC_Web.Models;
using DAL;



namespace FCTC_Web.Utilities
{
    public class Page<T> where T : class
    {
        public int RecordsInPage { get; set; }

        public List<T> List { get; set; }
        public List<T> CurrentRecords
        {
            get
            {
                if (List.Count <= RecordsInPage) return List;
                return List.GetRange(RecordIndexStart, Range);
            }
        }

        public int Range
        {
            get
            {
                return (RecordIndexEnd - RecordIndexStart) + 1;
            }
        }
        public Page(int? currentPage, List<T> list, int? recordsInPage = null)
        {
            RecordsInPage = recordsInPage == null ? 2 : (int)recordsInPage;

            int index = Convert.ToInt32(currentPage) == 0 ? 1 : Convert.ToInt32(currentPage);
            CurrentPage = Convert.ToInt32(index);

            List = list;

        }
        //列表项总数
        public int Count { get { return List.Count; } }
        //当前页面
        public int CurrentPage { get; set; }

        //当前页面最后一项
        public int RecordIndexEnd
        {
            get
            {
                return (CurrentPage) * RecordsInPage < Count ? (CurrentPage) * RecordsInPage - 1 : Count - 1;
            }
        }

        //当前页面第一项
        public int RecordIndexStart
        {
            get
            {
                return CurrentPage > 0 ? (CurrentPage - 1) * RecordsInPage : 0;
            }
        }

        public double LastPage
        {
            get { return Math.Ceiling((double)Count / (double)RecordsInPage); }

        }
    }

    public class Pager
    {
        public static Pager _ins = new Pager();
        public static Pager Ins
        {
            get { return _ins; }
        }
        protected int recordsInPage = 2;
        public int RecordsInPage
        {
            get
            {
                return recordsInPage;
            }
        }
        /// <summary>
        /// for index and relative page
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="relativeId"></param>
        /// <param name="pageId"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public Page<T> GetPage<T>(int? relativeId, int? pageId, string propertyName, params string[] includes) where T : class
        {
            var totalRecords = CH.GetAllData<T>(null, includes).FindAll(i => CheckValue(i, propertyName, relativeId));
            var page = new Page<T>(pageId, totalRecords, RecordsInPage);
            return page;
        }

        /// <summary>
        /// for index page
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="relativeId"></param>
        /// <param name="pageId"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public Page<T> GetPage<T>(int? pageId, Func<T, bool> filters, params string[] includes) where T : class
        {
            var totalRecords = CH.GetAllData<T>(filters, includes);

            var page = new Page<T>(pageId, totalRecords, RecordsInPage);
            return page;
        }

        public Page<T> GetPage<T>(int? pageId, Func<T, bool> filters) where T : class
        {
            var totalRecords = CH.GetAllData<T>(filters);

            var page = new Page<T>(pageId, totalRecords, RecordsInPage);
            return page;
        }

        /// <summary>
        /// for index page no filter
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="relativeId"></param>
        /// <param name="pageId"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public Page<T> GetPage<T>(int? pageId, params string[] includes) where T : class
        {
            var totalRecords = CH.GetAllData<T>(null, includes);

            var page = new Page<T>(pageId, totalRecords, RecordsInPage);
            return page;
        }

        /// <summary>
        /// for edit/create return to correct page
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="relativeId"></param>
        /// <param name="item"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public int? GetPageId<T>(int id) where T : EntityBase
        {
            var totalRecords = CH.GetAllData<T>();
            var r = totalRecords.SingleOrDefault<T>(i => i.ID == id);
            if (r == null) return 1;
            int? pageId = null;
            if (r != null)
                pageId = (int?)Math.Ceiling(((double)totalRecords.IndexOf(r) + 1) / RecordsInPage);

            return pageId;
        }

        /// <summary>
        /// for edit/create return to correct page
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="relativeId"></param>
        /// <param name="id">当前被编辑的ID</param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public int? GetPageId<T>(int? relativeId, int id, string propertyName) where T : EntityBase
        {
            var totalRecords = CH.GetAllData<T>().FindAll(i => CheckValue(i, propertyName, relativeId));

            var r = totalRecords.SingleOrDefault<T>(i => i.ID == id);
            if (r == null) return 1;

            int? pageId = null;
            if (r != null)
                pageId = (int?)Math.Ceiling(((double)totalRecords.IndexOf(r) + 1) / (int)RecordsInPage);

            return pageId;
        }



        private bool CheckValue(object i, string propertyName, int? relativeId)
        {

            var value = i.GetType().GetProperty(propertyName).GetValue(i, null);
            if (value == null)
                return false;
            else
                return (int)value == relativeId ? true : false;
        }
    }

    public class Pager6 : Pager
    {
        public static Pager _ins = new Pager6();
        public static Pager Ins
        {
            get { return _ins; }
        }
        public Pager6()
        {
            recordsInPage = 6;
        }

    }

    public class Pager20 : Pager
    {
        public static Pager _ins = new Pager20();
        public static Pager Ins
        {
            get { return _ins; }
        }
        public Pager20()
        {
            recordsInPage = 20;
        }
    }

    public class Pager10 : Pager
    {
        public static Pager10 _ins = new Pager10();
        public static Pager10 Ins
        {
            get { return _ins; }
        }

        public Pager10()
        {
            recordsInPage = 10;
        }
    }
}

